package com.bumptech.glide.request.transition;

import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;

import com.bumptech.glide.load.DataSource;

/**
 * A {@link TransitionFactory} for complex types that have a {@link Bitmap} inside.
 * The transitioning bitmap is wrapped in a {@link BitmapDrawable}.
 * Most commonly used with {@link DrawableCrossFadeFactory}.
 * <p>
 * {@link TransitionFactory}的实现类，内部包含一个{@link Bitmap}的复杂类型
 *
 * @param <R> The type of the composite object that contains the {@link Bitmap} to
 *            be transitioned.
 */
public abstract class BitmapContainerTransitionFactory<R> implements TransitionFactory<R> {
    private final TransitionFactory<Drawable> realFactory;

    // Public API.
    @SuppressWarnings("WeakerAccess")
    public BitmapContainerTransitionFactory(TransitionFactory<Drawable> realFactory) {
        this.realFactory = realFactory;
    }

    @Override
    public Transition<R> build(DataSource dataSource, boolean isFirstResource) {
        Transition<Drawable> transition = realFactory.build(dataSource, isFirstResource);
        return new BitmapGlideAnimation(transition);
    }

    /**
     * Retrieve the Bitmap from a composite object.
     * <p><b>Warning:</b> Do not convert any arbitrary object to Bitmap
     * via expensive drawing here, this method is called on the UI thread.</p>
     *
     * @param current composite object containing a Bitmap and some other information
     * @return the Bitmap contained within {@code current}
     */
    protected abstract Bitmap getBitmap(R current);

    private final class BitmapGlideAnimation implements Transition<R> {
        private final Transition<Drawable> transition;

        BitmapGlideAnimation(Transition<Drawable> transition) {
            this.transition = transition;
        }

        @Override
        public boolean transition(R current, ViewAdapter adapter) {
            Resources resources = adapter.getView().getResources();
            Drawable currentBitmap = new BitmapDrawable(resources, getBitmap(current));
            return transition.transition(currentBitmap, adapter);
        }
    }
}
